package com.logger;

import com.logger.handlers.AHandler;
import com.logger.handlers.HandlerManager;

import java.util.Date;

/**
 * 默认日志实现
 * Created by chenxunlin01 on 2016/1/16.
 */

public class MLogger extends Logger {

    private Option option;
    private String tag;

    public MLogger(Option option, String tag) {
        this.option = option;
        this.tag = tag;
    }

    @Override
    public void log(Level level, Object message, Throwable t) {
        if (option.getLevel().compare(level) > 0) {
            return;
        }
        StackTraceElement el = null;
        if (t == null) {
            el = new Throwable().getStackTrace()[3];
        } else {
            el = t.getStackTrace()[1];
        }
        String msg = message == null ? "null" : message.toString();
        ThrowableInfo throwableInfo = new ThrowableInfo(t, el);
        LogMessage logMessage = buildMessage(level, msg, throwableInfo);
        doLogger(logMessage);
    }

    @Override
    public void addHandler(AHandler handler) {
        if (HandlerManager.registerHandler(handler)) {
            option.getHandlerMap().put(handler.getName(), handler);
        }
    }

    @Override
    public AHandler removeHandler(AHandler handler) {
        return option.getHandlerMap().remove(handler);
    }

    private void doLogger(LogMessage logMessage) {
        LoggerPocket loggerPocket = null;
        Option option = this.option;
        for (AHandler handler : option.getHandlerMap().values()) {
            if (handler.isAsync()) {
                if (loggerPocket == null) {
                    loggerPocket = new LoggerPocket(logMessage);
                }
                loggerPocket.addHandler(handler);

            } else {
                handler.doHandler(logMessage);
            }
        }

        //添加到异步方式处理
        if (loggerPocket != null && !loggerPocket.isEmpty()) {
            LoggerAsync.offer(loggerPocket);
        }
    }

    /**
     * 构建日志消息
     *
     * @return
     */
    private LogMessage buildMessage(Level level, String msg, ThrowableInfo info) {
        LogMessage message = new LogMessage();
        message.setOption(option);
        message.setThreadName(Thread.currentThread().getName());
        message.setDate(new Date());
        message.setLevel(level);
        message.setMessage(msg);
        message.setThrowableInfo(info);
        message.setTag(tag);
        return message;
    }
}
